<?php
namespace Secret\Controllers;

use Secret\Common\Utils;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Silex\ControllerCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;

class ContentCSP implements ControllerProviderInterface {

	public function connect(Application $app) {
		$controllers = $app['controllers_factory'];
		$controllers->match('/remove/', array($this,'remove'), 'POST')->bind('remove-content');
		$controllers->match('/sort/', array($this,'sort'), 'POST')->bind('sort-contents');
		$controllers->match('/detail/{modelName}/{returnURL}/', array($this,'content'), 'GET')->bind('add-content');
		$controllers->match('/detail/{modelName}/{idValue}/{returnURL}/', array($this,'content'), 'GET')->bind('edit-content');
		$controllers->match('/{modelName}/', array($this,'contents'), 'GET')->bind('contents');
		$controllers->match('/{modelName}/Page{page}/', array($this,'contents'), 'GET')->bind('contents-by-page');
		$controllers->match('/{modelName}/Page{page}/{sort}/{order}/', array($this,'contents'), 'GET')->bind('contents-by-order');
		return $controllers;
	}

	public function contents(Application $app, $modelName, $page = 1, $sort = 'id', $order = 'DESC') {
		global $CMS_COLUMN_META;
		$repo = $app['em']->getRepository('Secret\Entities\Content');
		$model = $repo->model(urldecode($modelName));
		$sort = urldecode($sort);
		$content = array();
		$content['meta'] = $CMS_COLUMN_META;
		if ($model['resortable'] == 1) {
			$content['model'] = $repo->data($model, '', array(), array('sort' => 'rank','order' => 'ASC'));
		} else {
			$content['model'] = $repo->data($model, '', array(), array('page' => $page,'limit' => $model['numPerPage'],'sort' => $sort,'order' => $order));
		}
		$content['returnURL'] = \Secret\Common\Utils::getURL();
		if ($model['ownList'] == 1 && $model['twigList'] != '') {
			return $app['twig']->render($model['twigList'] . ".twig", $content);
		} else {
			return $app['twig']->render("contents.twig", $content);
		}
	}

	public function content(Application $app, Request $request, $modelName, $idValue = null, $returnURL = '') {
		global $CMS_COLUMN_TYPES_CUSTOM;
		
		$repo = $app['em']->getRepository('Secret\Entities\Content');
		$idValue = urldecode($idValue);
		$model = $repo->model(urldecode($modelName));
		$model = (! $idValue) ? $repo->create($model) : $repo->data($model, 'entity.slug = :v1', array('v1' => $idValue));
		if (count($model['_data']) == 0) {
			$model = $repo->data($model, 'entity.' . $model['idField'] . ' = :v1', array('v1' => $idValue));
		}
		if (count($model['_data']) == 0) {
			$app->abort(404);
		}
		
		foreach ($model['columnsJson'] as $itm) {
			if ($itm['type']['name'] == 'choice' && isset($itm['type']['options']['multiple']) && $itm['type']['options']['multiple']) {
				$model['_data'][0][$itm['field']] = json_decode($model['_data'][0][$itm['field']]);
				if (!$model['_data'][0][$itm['field']]) {
					$model['_data'][0][$itm['field']] = array();
				}
			} else if ($itm['type']['name'] == 'checkbox') {
				$model['_data'][0][$itm['field']] = $model['_data'][0][$itm['field']] == 1 ? true : false;
			} else if ($itm['type']['name'] == 'date' || $itm['type']['name'] == 'datetime' || $itm['type']['name'] == 'time' || $itm['type']['name'] == 'birthday') {
				$model['_data'][0][$itm['field']] = strtotime($model['_data'][0][$itm['field']]) ? new \DateTime($model['_data'][0][$itm['field']]) : new \DateTime();
			} else if ($itm['type']['name'] == '*FilePicker') {
				if (file_exists(dirname($_SERVER['SCRIPT_FILENAME']) . '/../uploads/' . $model['_data'][0]['nameOnServer']) && is_file(dirname($_SERVER['SCRIPT_FILENAME']) . '/../uploads/' . $model['_data'][0]['nameOnServer'])) {
					$model['_data'][0]['nameOnServer'] = new \Symfony\Component\HttpFoundation\File\File(dirname($_SERVER['SCRIPT_FILENAME']) . '/../uploads/' . $model['_data'][0]['nameOnServer']);
				}
			}
		}
		
		$form = $app['form.factory']->createBuilder('form', $model['_data'][0]);
		foreach ($model['columnsJson'] as $itm) {
			$type = isset($CMS_COLUMN_TYPES_CUSTOM[$itm['type']['name']]) ? $CMS_COLUMN_TYPES_CUSTOM[$itm['type']['name']] : $itm['type']['name'];
			$options = array(
				'label' => $itm['name'],
				'constraints' => $itm['field'] != $model['idField'] ? array() : array(
					new Assert\NotBlank(),
				),
			);
			foreach ($itm['type']['options'] as $key => $value) {
				if ($value == 'true') {
					$value = true;
				} else if ($value == 'false') {
					$value = false;
				}
				$options[$key] = $value;
			}
			if ($itm['type']['name'] == 'choice') {
				$query = $app['em']->createQuery($itm['type']['options']['choices']);
				$values = $query->getResult();
				$options['choices'] = array();
				foreach ($values as $value) {
					$options['choices'][$value['idx']] = $value['val'];
				}
			}
			$form->add($itm['field'], $type, $options);

		}
		$form = $form->getForm();
		
		if ($request->getMethod() == 'POST') {
			$user = $app['user']->getUser();
			if ((!$user || $user->admin == 0) && $model['permission'] == 1) {
				return $app->abort(401);
			}
			
			$form->bind($request);
			if ($form->isValid()) {
				$data = $form->getData();
				foreach ($data as $idx => $itm) {
					if (isset($model['_data'][0][$idx])) {
						if (gettype($model['_data'][0][$idx]) == 'object') {
							$model['_data'][0]['nameOnServer'] = $idValue;
						} else {
							$model['_data'][0][$idx] = $itm;
						}
					}
				}

				$files = $request->files->get($form->getName());
				if (isset($files) && $files && is_array($files) && count($files) > 0 && $files['nameOnServer']) {
					$thumbnail = dirname($_SERVER['SCRIPT_FILENAME']) . '/../cache/image/' . md5($model['_data'][0]['id'] . '-290') . '.' . $model['_data'][0]['fileExt'];
					if (file_exists($thumbnail)) {
						unlink($thumbnail);
					}
					$model['_data'][0]['name'] = $files['nameOnServer']->getClientOriginalName();
					$model['_data'][0]['fileExt'] = $files['nameOnServer']->guessExtension();
					$model['_data'][0]['fileType'] = $files['nameOnServer']->getMimeType();
					$model['_data'][0]['fileSize'] = $files['nameOnServer']->getClientSize();
					$files['nameOnServer']->move(dirname($_SERVER['SCRIPT_FILENAME']) . '/../uploads/', $idValue);
				}
				
				$repo->save($model);
				if ($request->request->get('action') == 'Submit & back') {
					return $app->redirect(urldecode($returnURL));
				} else {
					return $app->redirect($app['url_generator']->generate('edit-content', array('modelName' => $modelName, 'idValue' => $model['_data'][0]['slug'] != '' ? $model['_data'][0]['slug'] : urlencode($model['_data'][0][$model['idField']]), 'returnURL' => $returnURL)));
				}
			}
		}
		
		if ($model['ownDetail'] == 1 && $model['twigDetail'] != '') {
			return $app['twig']->render($model['twigDetail'] . ".twig", array('returnURL' => urldecode($returnURL),'model' => $model,'form' => $form->createView()));
		} else {
			return $app['twig']->render("content.twig", array('returnURL' => urldecode($returnURL),'model' => $model,'form' => $form->createView()));
		}
	}
	
	public function remove(Application $app, Request $request) {
		$modelName = $request->get('modelName');
		$repo = $app['em']->getRepository('Secret\Entities\Content');
		$model = $repo->model(urldecode($modelName));
		$user = $app['user']->getUser();
		if ((!$user || $user->admin == 0) && $model['permission'] == 1) {
			return $app->abort(401);
		}
		
		$data = $request->get('data');
		$entity = $repo->find($data);
		if ($entity) {
			$app['em']->remove($entity);
			$app['em']->flush();
		}
		return new Response('Success');
	}

	public function sort(Application $app, Request $request) {
		$data = json_decode($request->get('data'));
		$repo = $app['em']->getRepository('Secret\Entities\Content');
		foreach ($data as $idx => $itm) {
			$entity = $repo->find($itm);
			if ($entity) {
				$entity->setRank($idx);
				$app['em']->persist($entity);
			}
		}
		$app['em']->flush();
		return new Response('Success');
	}
}